#ifndef _FXAPI_H
	#define _FXAPI_H

#include "_ExternalDefinitions.h"

//////////////////////////////////////////////////////////////////////////////////////////
//                            Parameters definition
//////////////////////////////////////////////////////////////////////////////////////////

#define FX_INFO_SENTENCE       1
#define FX_INFO_ENTITY         2
#define FX_INFO_RELATIONSHIP   3
#define FX_INFO_FRAME          4
#define FX_INFO_FRAME_SLOT     5
#define FX_INFO_CONTEXT        6

#define FX_INFO_TARGET_ENTITY_FOR_RELATIONSHIP       10
#define FX_INFO_CONNECTOR_ENTYTY_FOR_RELATIONSHIP    11
#define FX_INFO_ENTITY_FOR_FRAME_SLOT                12
#define FX_INFO_SENTENCE_FOR_ENTITY                  13
#define FX_INFO_ENTITY_FOR_CONTEXT                   14
#define FX_INFO_ENTITY_COREFERENT                    15

#define FX_PARAM_ENTITYNAME_MAX_LENGTH          1
#define FX_PARAM_ENTITYNAME_MAX_COUNT           2
#define FX_PARAM_ENTITYNAME_HOMONYMS            3
#define FX_PARAM_ENTITYNAME_SUBNAMES            4
#define FX_PARAM_ENTITYNAME_RELATION_SET        5
#define FX_PARAM_ENTITYNAME_GENERATION_FLAGS    6


//////////////////////////////////////////////////////////////////////////////////////////
//                               Basic types definition
//////////////////////////////////////////////////////////////////////////////////////////

// types of errors
enum FX_ERROR
{
    FX_SUCCESS = 0, // No errors
    FX_WARN_NO_MORE_RESULTS = 1, // No more result is available.
    FX_WARN_DATA_TRUNCATED = 2, // Only part of data was returned.
    FX_ERR_BAD_PARAMETER = -1, // The parameter has invalid value.
    FX_ERR_BAD_CONFIG_PATH = -2, // Specified path for configuration file does not exist.
    FX_ERR_BAD_CONFIG_FORMAT = -3, // Configuration file has bad syntax.
    FX_ERR_UNSUPPORTED_FEATURE = -4, // Feature specified in the configuration file is not supported
    FX_ERR_BAD_INPUTTEXT = -5, // Input text has unsupported format.
    FX_ERR_OUT_OF_MEMORY = -6, // Out of memory to perform this operation.
    FX_ERR_BUFFER_TOO_SMALL = -7, // The supplied buffer size is too small.
    FX_ERR_BAD_IDENTIFIER = -8, // Invalid sentence, entity, or relationship identifier.
    FX_ERR_BAD_HANDLE = -9, // Invalid context or result handle.
    FX_ERR_NO_SUCH_ATTR = -10, // Entity or relationship does not have attribute with such identifier.
    FX_ERR_NO_VALUE = -11, // Attribute does not have value with such index.
    FX_ERR_RESOURCE_NOT_FOUND = -12, // Specified resource does not exist.
    FX_ERR_INTERNAL = -13,  // Internal error
		FX_ERR_EXTERNAL_MODULE_FAIL = -14,
		FX_ERR_NOT_ACCESSIBLE_IN_THIS_VERSION = -15
};

typedef void* FX_HANDLE;

typedef void* FX_ID;


static string _FXGetIDStringValue( const FX_ID &idID )
{
	char aszBuf[32];
	sprintf_s( aszBuf, 32, "%p", idID );
	return string(aszBuf);
}


// manager of external resources
typedef void* FX_RESOURCE_HANDLE;

struct FX_RESOURCE_MANAGER
{
 virtual FX_RESOURCE_HANDLE Open(const wchar_t* szResourceId) = 0;
 virtual void Close(FX_RESOURCE_HANDLE hResource) = 0;
 virtual bool Read(FX_RESOURCE_HANDLE hResource, void* pBuffer, unsigned long ulNumberOfBytesToRead, unsigned long* pulNumberOfBytesRead) = 0;
};


//////////////////////////////////////////////////////////////////////////////////////////
//                               API functions
//////////////////////////////////////////////////////////////////////////////////////////
#define _FXAPI(ret) extern "C" ret __stdcall 

_FXAPI(FX_ERROR) FXCreateContext( const wchar_t* szConfig, FX_RESOURCE_MANAGER* pResManager, FX_HANDLE* phHandle );
_FXAPI(FX_ERROR) FXDestroyContext( FX_HANDLE hContext );

_FXAPI(FX_ERROR) FXProcessText( FX_HANDLE hContext, const wchar_t* szText, const wchar_t* szTextID, FX_TEXT_FORMAT eFormat, FX_HANDLE* phResult );
_FXAPI(FX_ERROR) FXDestroyResult( FX_HANDLE hResult );

_FXAPI(FX_ERROR) FXSetEntityNameGenerationMode( FX_HANDLE hResult, unsigned short idParam, long nValue );
_FXAPI(FX_ERROR) FXGetEntityNameGenerationMode( FX_HANDLE hResult, unsigned short idParam, long* pnValue );

_FXAPI(FX_ERROR) FXGetFirst( FX_HANDLE hResult, const FX_ID* pidSource, unsigned long InfoType, FX_ID* pidTarget );
_FXAPI(FX_ERROR) FXGetNext(  FX_HANDLE hResult, const FX_ID* pidSource, unsigned long InfoType, FX_ID* pidTarget );

_FXAPI(FX_ERROR) FXGetAttributeValueCount( FX_HANDLE hResult, const FX_ID* pidSource, unsigned long AttrID, unsigned short* puValueCount );
_FXAPI(FX_ERROR) FXGetAttributeValue( FX_HANDLE hResult, const FX_ID* pidSource, unsigned long AttrID, unsigned short uValueIndex, unsigned long* pulBufferSize, void* pBuffer );

_FXAPI(FX_ERROR) FXGetPrev(  FX_HANDLE hResult, const FX_ID* pidSource, unsigned long InfoType, FX_ID* pidTarget );

///////////////////////////////////////////////////////////////////////////////////////////
//                          Attributes definitions
///////////////////////////////////////////////////////////////////////////////////////////

// types of attributes
enum FX_ATTR_TYPE
{
    FX_ATTRTYPE_BOOL = 1, // Corresponds to bool C++ type
    FX_ATTRTYPE_LONG = 2, // Corresponds to long C++ type
    FX_ATTRTYPE_STRING = 3 // Corresponds to wchar_t* C++ type
};

// groups of attributes
#define FX_GROUP_SENTENCE 1
#define FX_GROUP_ENTITY 2
#define FX_GROUP_RELATIONSHIP 3
#define FX_GROUP_MORPH 4
#define FX_GROUP_FRAME 5
#define FX_GROUP_CONTEXT 6

#define _DEFINE_ATTR(group, type, code) (unsigned long)((group<<24) | (type<<16) | code)

#define ATTR_GROUP(id)  ((id) >> 24)
#define ATTR_TYPE(id)   (((id) >> 16) & 0x000f)
#define ATTR_NUM(id)    ((id) & 0x00ff)

// attributes of sentence 
#define FX_ATTR_SENTENCE_TYPE              _DEFINE_ATTR(FX_GROUP_SENTENCE, FX_ATTRTYPE_LONG,      1)
#define FX_ATTR_SENTENCE_OFFSET            _DEFINE_ATTR(FX_GROUP_SENTENCE, FX_ATTRTYPE_LONG,      2)
#define FX_ATTR_SENTENCE_LENGTH            _DEFINE_ATTR(FX_GROUP_SENTENCE, FX_ATTRTYPE_LONG,      3)
#define FX_ATTR_SENTENCE_TEXT              _DEFINE_ATTR(FX_GROUP_SENTENCE, FX_ATTRTYPE_STRING,    4)

// grammar attributes of entity
#define FX_ATTR_MORPH_FIRSTCODE             _DEFINE_ATTR(FX_GROUP_MORPH, FX_ATTRTYPE_LONG,        1)
#define FX_ATTR_MORPH_SPEECHPART            _DEFINE_ATTR(FX_GROUP_MORPH, FX_ATTRTYPE_LONG,        1)
// #ifdef RCO_FX_PROFESSIONAL //  for professional version only
	#define FX_ATTR_MORPH_FORMINDEX             _DEFINE_ATTR(FX_GROUP_MORPH, FX_ATTRTYPE_LONG,      2)
	#define FX_ATTR_MORPH_PARADIGMTYPE          _DEFINE_ATTR(FX_GROUP_MORPH, FX_ATTRTYPE_LONG,      3)
// #endif 
#define FX_ATTR_MORPH_LASTCODE              _DEFINE_ATTR(FX_GROUP_MORPH, FX_ATTRTYPE_LONG,        3)

// attributes of entity
#define FX_ATTR_ENTITY_COMMONTYPE           _DEFINE_ATTR(FX_GROUP_ENTITY, FX_ATTRTYPE_LONG,        1)
#define FX_ATTR_ENTITY_TYPE                 _DEFINE_ATTR(FX_GROUP_ENTITY, FX_ATTRTYPE_STRING,      2)
#define FX_ATTR_ENTITY_NAMELENGTH           _DEFINE_ATTR(FX_GROUP_ENTITY, FX_ATTRTYPE_LONG,        3)
#define FX_ATTR_ENTITY_NAME                 _DEFINE_ATTR(FX_GROUP_ENTITY, FX_ATTRTYPE_STRING,      4)
#define FX_ATTR_ENTITY_NAMETYPE             _DEFINE_ATTR(FX_GROUP_ENTITY, FX_ATTRTYPE_LONG,        5)
#define FX_ATTR_ENTITY_NAMETEMPLATE         _DEFINE_ATTR(FX_GROUP_ENTITY, FX_ATTRTYPE_STRING,      6)
#define FX_ATTR_ENTITY_OFFSET               _DEFINE_ATTR(FX_GROUP_ENTITY, FX_ATTRTYPE_LONG,        7)
#define FX_ATTR_ENTITY_LENGTH               _DEFINE_ATTR(FX_GROUP_ENTITY, FX_ATTRTYPE_LONG,        8)
#define FX_ATTR_ENTITY_TEXT                 _DEFINE_ATTR(FX_GROUP_ENTITY, FX_ATTRTYPE_STRING,      9)
#define FX_ATTR_ENTITY_ATTRIBUTES           _DEFINE_ATTR(FX_GROUP_ENTITY, FX_ATTRTYPE_STRING,      10)
#define FX_ATTR_ENTITY_PARTOFSENTENCE       _DEFINE_ATTR(FX_GROUP_ENTITY, FX_ATTRTYPE_LONG,        11)
#define FX_ATTR_ENTITY_CLAUSETYPE           _DEFINE_ATTR(FX_GROUP_ENTITY, FX_ATTRTYPE_LONG,        12)
#define FX_ATTR_ENTITY_TAXISINFO            _DEFINE_ATTR(FX_GROUP_ENTITY, FX_ATTRTYPE_LONG,        13)

// attributes of relationship
// #ifdef RCO_FX_PROFESSIONAL // for professional version only
	#define FX_ATTR_RELATIONTYPE                _DEFINE_ATTR(FX_GROUP_RELATIONSHIP, FX_ATTRTYPE_LONG,   1)
	#define FX_ATTR_RELATIONCASE                _DEFINE_ATTR(FX_GROUP_RELATIONSHIP, FX_ATTRTYPE_LONG,   2)
	#define FX_ATTR_RELATIONCONNECTOR           _DEFINE_ATTR(FX_GROUP_RELATIONSHIP, FX_ATTRTYPE_STRING, 3)
	#define FX_ATTR_RELATIONROLE                _DEFINE_ATTR(FX_GROUP_RELATIONSHIP, FX_ATTRTYPE_STRING, 4)
	#define FX_ATTR_RELATION_IS_KNOWN           _DEFINE_ATTR(FX_GROUP_RELATIONSHIP, FX_ATTRTYPE_LONG,   5)
// #endif // RCO_FX_PROFESSIONAL

// attributes of frame
#define FX_ATTR_FRAME_CLASS                _DEFINE_ATTR(FX_GROUP_FRAME, FX_ATTRTYPE_STRING,      1)
#define FX_ATTR_FRAME_TEMPLATE             _DEFINE_ATTR(FX_GROUP_FRAME, FX_ATTRTYPE_STRING,      2)
#define FX_ATTR_FRAME_SLOT_NAME            _DEFINE_ATTR(FX_GROUP_FRAME, FX_ATTRTYPE_STRING,      3)
#define FX_ATTR_FRAME_SLOT_RESTRICTION     _DEFINE_ATTR(FX_GROUP_FRAME, FX_ATTRTYPE_STRING,      4)
#define FX_ATTR_FRAME_BASIC_CLASS          _DEFINE_ATTR(FX_GROUP_FRAME, FX_ATTRTYPE_STRING,      5)

// attributes of context
#define FX_ATTR_CONTEXT_TYPE               _DEFINE_ATTR(FX_GROUP_CONTEXT, FX_ATTRTYPE_LONG,      1)

#endif //_FXAPI_H